#ifndef PROTOKOL_H
#define PROTOKOL_H

#include"definicje.h"
#include<inttypes.h>
#include<stdbool.h>
#include<sys/types.h>
#include<sys/socket.h>

#define MAX_PAKIET 10000

#define OP_ACK 1
#define OP_ERR 2
#define OP_DAT 3
#define OP_CAN 4
#define OP_SET 5
#define OP_LIST 6
#define OP_GET 7
#define OP_QUIT 8

#define poprawnaOperacja(x) ((x)==OP_ACK || (x)==OP_ERR || (x)==OP_DAT || (x)==OP_CAN || (x)==OP_SET || (x)==OP_LIST || (x)==OP_GET || (x)==OP_QUIT)

#define rozmiarNaglowka 12
struct naglowek
{
   uint16_t rozmiar; // rozmiar danych
   uint8_t operacja; // identyfikator operacji
   uint8_t opcje; // dodatkowe opcje
   uint32_t ktory; // ktory blok
   uint32_t suma; // suma kontrolna
};

#define rozmiarACK 16
struct pakietACK
{
   struct naglowek naglowek;
   uint32_t ktory;
};

#define rozmiarERR 16
struct pakietERR
{
   struct naglowek naglowek;
   uint32_t ktory;
};

#define rozmiarSET 14
struct pakietSET
{
   struct naglowek naglowek;
   uint16_t rozmiar;
};

void obliczsume(uint8_t *d);
bool czypoprawny(uint8_t *d);

int wyslijpakiet(
      const int gniazdo,
      const struct sockaddr_storage * const adres,
      uint8_t * const d
      );

int odbierzpakiet(
      const int gniazdo,
      struct sockaddr_storage * const adres,
      uint8_t * const d
      );

int wyslijzpotw(
      const int gniazdo,
      const struct sockaddr_storage * const adres,
      uint8_t * const d,
      uint8_t * const dp,
      uint32_t * const ktory,
      uint32_t * const ktoryp
      );

int odbierzzpotw(
      const int gniazdo,
      struct sockaddr_storage * const adres,
      uint8_t * const d,
      uint32_t * const ktory,
      uint32_t * const ktoryp
      );

#endif
